package net.lab1024.sa.base.module.support.traffic.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.traffic.dao.TrafficHistoryDao;
import net.lab1024.sa.base.module.support.traffic.domain.dto.MqttHeartbeatDTO;
import net.lab1024.sa.base.module.support.traffic.domain.dto.MqttHeartbeatResponseDTO;
import net.lab1024.sa.base.module.support.traffic.domain.dto.MqttResponseDTO;
import net.lab1024.sa.base.module.support.traffic.domain.entity.TrafficHeartbeatHistoryEntity;
import net.lab1024.sa.base.module.support.traffic.domain.entity.TrafficResponseHistoryEntity;
import net.lab1024.sa.base.module.support.traffic.domain.form.TrafficHeartbeatHistoryQueryForm;
import net.lab1024.sa.base.module.support.traffic.domain.form.TrafficResponseHistoryQueryForm;
import net.lab1024.sa.base.module.support.traffic.domain.vo.TrafficHeartbeatHistoryVO;
import net.lab1024.sa.base.module.support.traffic.domain.vo.TrafficResponseHistoryVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 交通历史记录服务
 */
@Slf4j
@Service
public class TrafficHistoryService {

    private static final Pattern TOPIC_PATTERN = Pattern.compile(".*/intersection/([^/]+)/lane/lane_(\\d+)/.*");

    @Resource
    private TrafficHistoryDao trafficHistoryDao;

    /**
     * 保存心跳记录
     */
    public void saveHeartbeat(String topic, MqttHeartbeatDTO heartbeatDTO) {
        DeviceInfo deviceInfo = parseDeviceInfo(topic);
        if (deviceInfo == null) {
            log.warn("无法从Topic解析设备信息: {}", topic);
            return;
        }
        TrafficHeartbeatHistoryEntity entity = new TrafficHeartbeatHistoryEntity();
        entity.setDeviceRoad(deviceInfo.deviceRoad());
        entity.setDeviceId(deviceInfo.deviceId());
        entity.setRequestId(heartbeatDTO.getRequestId());
        entity.setCurrentMode(heartbeatDTO.getCurrentMode());
        entity.setIntervalSecond(parseInteger(heartbeatDTO.getInterval()));
        entity.setMessageTimestamp(heartbeatDTO.getTimestamp());
        entity.setCreateTime(LocalDateTime.now());
        try {
            trafficHistoryDao.insertHeartbeat(entity);
        } catch (Exception e) {
            log.error("保存交通心跳历史失败", e);
        }
    }

    /**
     * 保存响应记录
     */
    public void saveResponse(String topic, MqttResponseDTO responseDTO) {
        DeviceInfo deviceInfo = parseDeviceInfo(topic);
        if (deviceInfo == null) {
            log.warn("无法从Topic解析设备信息: {}", topic);
            return;
        }
        TrafficResponseHistoryEntity entity = new TrafficResponseHistoryEntity();
        entity.setDeviceRoad(deviceInfo.deviceRoad());
        entity.setDeviceId(deviceInfo.deviceId());
        entity.setRequestId(responseDTO.getRequestId());
        entity.setStatus(responseDTO.getStatus());
        entity.setMessage(responseDTO.getMessage());
        entity.setCurrentMode(responseDTO.getCurrentMode());
        entity.setIntervalSecond(parseInteger(responseDTO.getInterval()));
        entity.setFlashtimeSecond(parseInteger(responseDTO.getFlashtime()));
        entity.setMessageTimestamp(responseDTO.getTimestamp());
        entity.setCreateTime(LocalDateTime.now());
        try {
            trafficHistoryDao.insertResponse(entity);
        } catch (Exception e) {
            log.error("保存交通响应历史失败", e);
        }
    }

    /**
     * 保存心跳响应记录（平台->设备）
     */
    public void saveHeartbeatResponse(String topic, MqttHeartbeatResponseDTO responseDTO) {
        DeviceInfo deviceInfo = parseDeviceInfo(topic);
        if (deviceInfo == null) {
            log.warn("无法从Topic解析设备信息: {}", topic);
            return;
        }
        TrafficResponseHistoryEntity entity = new TrafficResponseHistoryEntity();
        entity.setDeviceRoad(deviceInfo.deviceRoad());
        entity.setDeviceId(deviceInfo.deviceId());
        entity.setRequestId(responseDTO.getRequestId());
        entity.setStatus(responseDTO.getStatus());
        entity.setMessage(responseDTO.getMessage());
        entity.setMessageTimestamp(responseDTO.getTimestamp());
        entity.setCreateTime(LocalDateTime.now());
        try {
            trafficHistoryDao.insertResponse(entity);
        } catch (Exception e) {
            log.error("保存交通心跳响应历史失败", e);
        }
    }

    /**
     * 分页查询心跳历史
     */
    public ResponseDTO<PageResult<TrafficHeartbeatHistoryVO>> queryHeartbeatHistory(TrafficHeartbeatHistoryQueryForm queryForm) {
        Page<?> pageQuery = SmartPageUtil.convert2PageQuery(queryForm);
        List<TrafficHeartbeatHistoryVO> list = trafficHistoryDao.pageQueryHeartbeat(pageQuery, queryForm);
        PageResult<TrafficHeartbeatHistoryVO> pageResult = SmartPageUtil.convert2PageResult(pageQuery, list);
        return ResponseDTO.ok(pageResult);
    }

    /**
     * 分页查询响应历史
     */
    public ResponseDTO<PageResult<TrafficResponseHistoryVO>> queryResponseHistory(TrafficResponseHistoryQueryForm queryForm) {
        Page<?> pageQuery = SmartPageUtil.convert2PageQuery(queryForm);
        List<TrafficResponseHistoryVO> list = trafficHistoryDao.pageQueryResponse(pageQuery, queryForm);
        PageResult<TrafficResponseHistoryVO> pageResult = SmartPageUtil.convert2PageResult(pageQuery, list);
        return ResponseDTO.ok(pageResult);
    }

    private DeviceInfo parseDeviceInfo(String topic) {
        if (StringUtils.isBlank(topic)) {
            return null;
        }
        Matcher matcher = TOPIC_PATTERN.matcher(topic);
        if (!matcher.matches()) {
            return null;
        }
        String deviceRoad = matcher.group(1);
        Integer deviceId = Integer.valueOf(matcher.group(2));
        return new DeviceInfo(deviceRoad, deviceId);
    }

    private Integer parseInteger(String value) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        try {
            return Integer.valueOf(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private record DeviceInfo(String deviceRoad, Integer deviceId) {
    }
}

